﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Data;
using System.Text;

using DatabaseCompare.Model;
using DatabaseCompare.Service.Reader;

namespace DatabaseCompare.ServiceImpl.Reader
{

    /// <summary>
    /// 抽象数据库读取.
    /// </summary>
    public abstract class AbstractDatabaseInfoReader : IDatabaseInfoReader
    {

        /// <summary>
        /// 将数据库信息，读取到 DataSet 中.
        /// </summary>
        /// <returns></returns>
        public abstract DataSet ReadDatabaseInfoToDataSet();



        #region IDatabaseInfoReader 成员


        /// <summary>
        /// 连接字符串.
        /// </summary>
        private string connectString;


        /// <summary>
        /// 数据库名称.
        /// </summary>
        private string databaseName;



        public string ConnectString
        {
            get
            {
                return connectString;
            }
            set
            {
                connectString = value;
            }
        }

        public string DatabaseName
        {
            get
            {
                return databaseName;
            }
            set
            {
                databaseName = value;
            }
        }


        /// <summary>
        /// 读取.
        /// </summary>
        /// <returns></returns>
        public DatabaseInfo ReadDatabaseInfo()
        {
            DataSet ds = ReadDatabaseInfoToDataSet();

            DatabaseInfo result = new DatabaseInfo();
            result.Name = databaseName;
            

            #region 表的处理.

            // 初始化表List.
            result.TableList = new List<TableInfo>();

            // 先加表.
            foreach (DataRow row in ds.Tables["TableInfo"].Rows)
            {
                // 依次处理每一个表.
                TableInfo tableInfo = new TableInfo();
                // 表名.
                tableInfo.Name = row["TableName"].ToString();
                // 备注.
                tableInfo.Comment = row["Comment"].ToString();
                // 处理完毕后，表加入结果列表.
                result.TableList.Add(tableInfo);
            }



            // 再加列.
            foreach (TableInfo tableInfo in result.TableList)
            {
                // 初始化 列的列表.
                tableInfo.SubList = new List<ColumnInfo>();

                // 检索当前表的列.
                DataRow[] rows = ds.Tables["TableColumnInfo"].Select("TableName='" + tableInfo.Name + "'", "ColumnId");

                for (int i = 0; i < rows.Length; i++)
                {
                    DataRow row = rows[i];
                    // 读取每一列.
                    ColumnInfo columnInfo = new ColumnInfo();
                    // 列名
                    columnInfo.Name = row["ColumnName"].ToString();
                    // 列的顺序
                    columnInfo.ColumnId = Convert.ToInt32(row["ColumnId"]);
                    // 数据类型
                    columnInfo.DataType = row["ColumnName"].ToString();
                    // 占用字节数
                    columnInfo.MaxLength = Convert.ToInt32(row["MaxLength"]);
                    // 长度
                    columnInfo.Precision = Convert.ToInt32(row["Precision"]);
                    // 小数位数
                    columnInfo.Scale = Convert.ToInt32(row["Scale"]);
                    // 是否允许非空
                    columnInfo.IsNullAble = Convert.ToInt32(row["IsNullAble"]) == 1;
                    // 是否是自增ID
                    columnInfo.IsIDEntity = Convert.ToInt32(row["IsIDEntity"]) == 1;
                    // 是否是主键
                    columnInfo.IsPrimaryKey = Convert.ToInt32(row["IsPrimaryKey"]) == 1;
                    // 备注/说明信息
                    columnInfo.Comment = row["Comment"].ToString();


                    // 列加入表的列List.
                    tableInfo.SubList.Add(columnInfo);
                }
            }


            #endregion 表的处理.


            #region 视图的处理.

            // 初始化视图List.
            result.ViewList = new List<ViewInfo>();

            // 再加视图.
            foreach (DataRow row in ds.Tables["ViewInfo"].Rows)
            {
                // 依次处理每一个视图.
                ViewInfo viewInfo = new ViewInfo();
                // 视图名.
                viewInfo.Name = row["ViewName"].ToString();
                // 备注.
                viewInfo.Comment = row["Comment"].ToString();
                // 创建视图的语句.
                viewInfo.CreateViewSQL = row["CreateViewSQL"].ToString();

                // 处理完毕后，加入结果列表.
                result.ViewList.Add(viewInfo);
            }

            // 再加视图的列.
            foreach (ViewInfo viewInfo in result.ViewList)
            {
                // 初始化 列的列表.
                viewInfo.SubList = new List<ColumnInfo>();

                // 检索当前表的列.
                DataRow[] rows = ds.Tables["ViewColumnInfo"].Select("ViewName='" + viewInfo.Name + "'", "ColumnId");

                for (int i = 0; i < rows.Length; i++)
                {
                    DataRow row = rows[i];
                    // 读取每一列.
                    ColumnInfo columnInfo = new ColumnInfo();
                    // 列名
                    columnInfo.Name = row["ColumnName"].ToString();
                    // 列的顺序
                    columnInfo.ColumnId = Convert.ToInt32(row["ColumnId"]);
                    // 数据类型
                    columnInfo.DataType = row["ColumnName"].ToString();
                    // 占用字节数
                    columnInfo.MaxLength = Convert.ToInt32(row["MaxLength"]);
                    // 长度
                    columnInfo.Precision = Convert.ToInt32(row["Precision"]);
                    // 小数位数
                    columnInfo.Scale = Convert.ToInt32(row["Scale"]);
                    // 是否允许非空
                    columnInfo.IsNullAble = Convert.ToInt32(row["IsNullAble"]) == 1;
                    // 是否是自增ID
                    columnInfo.IsIDEntity = Convert.ToInt32(row["IsIDEntity"]) == 1;
                    // 是否是主键
                    columnInfo.IsPrimaryKey = Convert.ToInt32(row["IsPrimaryKey"]) == 1;
                    // 备注/说明信息
                    columnInfo.Comment = row["Comment"].ToString();


                    // 列加入 视图的列List.
                    viewInfo.SubList.Add(columnInfo);
                }
            }

            #endregion 视图的处理.


            #region 触发器的处理.

            // 初始化触发器List.
            result.TriggerList = new List<TriggerInfo>();

            // 再加触发器.
            foreach (DataRow row in ds.Tables["TriggerInfo"].Rows)
            {
                // 依次处理每一个.
                TriggerInfo triggerInfo = new TriggerInfo();
                // 名称.
                triggerInfo.Name = row["TriggerName"].ToString();
                // 备注.
                triggerInfo.Comment = row["Comment"].ToString();

                // 是否禁用.
                triggerInfo.IsDisable = Convert.ToInt32(row["IsDisable"]) == 1;
                // 是否 IsInsteadOf 触发器.
                triggerInfo.IsInsteadOfTrigger = Convert.ToInt32(row["IsInsteadOfTrigger"]) == 1;
                // 创建触发器的语句.
                triggerInfo.CreateSQL = row["CreateTriggerSQL"].ToString();

                // 处理完毕后，加入结果列表.
                result.TriggerList.Add(triggerInfo);
            }

            #endregion 触发器的处理.


            #region 存储过程的处理.

            // 初始化 存储过程List.
            result.ProcedureList = new List<ProcedureInfo>();

            // 再加存储过程.
            foreach (DataRow row in ds.Tables["ProcedureInfo"].Rows)
            {
                // 依次处理每一个.
                ProcedureInfo procedureInfo = new ProcedureInfo();
                // 名称.
                procedureInfo.Name = row["ProcedureName"].ToString();
                // 备注.
                procedureInfo.Comment = row["Comment"].ToString();

                // 创建 的语句.
                procedureInfo.CreateSQL = row["CreateProcedureSQL"].ToString();

                // 处理完毕后，加入结果列表.
                result.ProcedureList.Add(procedureInfo);
            }

            #endregion 存储过程的处理.



            #region 函数的处理.

            // 初始化 函数 List.
            result.FunctionList = new List<FunctionInfo>();

            // 函数.
            foreach (DataRow row in ds.Tables["FunctionInfo"].Rows)
            {
                // 依次处理每一个.
                FunctionInfo functionInfo = new FunctionInfo();
                // 名称.
                functionInfo.Name = row["FunctionName"].ToString();
                // 备注.
                functionInfo.Comment = row["Comment"].ToString();

                // 创建的语句.
                functionInfo.CreateSQL = row["CreateFunctionSQL"].ToString();

                // 处理完毕后，加入结果列表.
                result.FunctionList.Add(functionInfo);
            }

            #endregion 函数的处理.



            return result;

        }



        #endregion IDatabaseInfoReader 成员



    }

}
